using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;

/// <summary>
/// This code is totally free and open. You may reuse it in any way you wish.
/// </summary>
namespace Catapult 
{
public class ColorPicker : System.Web.UI.UserControl, IPostBackEventHandler
{
    Table tblShow;
    TableRow rowShow;
    Table tblPicker;
    TableCell cellPreview;
    TableRow rowPalettes;
    TableCell cellPal1;
    TableCell cellPal2;
    TableCell cellPal3;
    TableCell cellPal4;
    TableCell cellPal5;

    protected override void Render(HtmlTextWriter writer)
    {
        createTable();
        drawTable(writer);
        base.Render(writer);
    }

    private void createTable()
    {
        tblPicker = new Table();
        tblPicker.ID = "tblPicker";
        tblPicker.CellPadding = 0;
        tblPicker.CellSpacing = 0;
        tblPicker.BorderColor = System.Drawing.Color.Black;
        tblPicker.BorderStyle = BorderStyle.Solid;
        tblPicker.BorderWidth = new Unit(1);

        tblShow = new Table();
        tblShow.ID = "tblShow";
        tblShow.CellPadding = 0;
        tblShow.CellSpacing = 0;

        rowShow = new TableRow();
        rowShow.ID = "rowShow";
        rowShow.BorderColor = System.Drawing.Color.Black;
        rowShow.BorderStyle = BorderStyle.Solid;
        rowShow.BorderWidth = new Unit(1);

        cellPreview = new TableCell();
        cellPreview.ID = "cellPreview";
        cellPreview.Text = "#FFFFFF";
        cellPreview.Width = new Unit(100, UnitType.Percentage);
        cellPreview.ColumnSpan = 5;
        cellPreview.HorizontalAlign = HorizontalAlign.Center;

        rowShow.Cells.Add(cellPreview);
        tblShow.Rows.Add(rowShow);

        rowPalettes = new TableRow();
        rowPalettes.ID = "rowPalettes";
        rowPalettes.BorderColor = System.Drawing.Color.Black;
        rowPalettes.BorderStyle = BorderStyle.Solid;
        rowPalettes.BorderWidth = new Unit(1);


        TableCell MyCell;
        string id;
        for (int x = 1; x <= 5; x++)
        {
            id = "cellPal" + x.ToString();
            MyCell = (TableCell)this.FindControl(id);
            if (MyCell != null) {
                MyCell.ID = id;
                MyCell.Width = new Unit(20, UnitType.Percentage);
                MyCell.Text = x.ToString();
                MyCell.HorizontalAlign = HorizontalAlign.Center;
                MyCell.BorderColor = System.Drawing.Color.Black;
                MyCell.BorderStyle = BorderStyle.Dotted;
                MyCell.BorderWidth = new Unit(1);
                MyCell.BackColor = System.Drawing.Color.White;
                MyCell.ForeColor = System.Drawing.Color.Black;
                MyCell.Style.Add(HtmlTextWriterStyle.Cursor, "hand");
                rowPalettes.Cells.Add(MyCell);
            }
        }

        tblShow.Rows.Add(rowPalettes);
 
    }
    private void drawTable(HtmlTextWriter writer)
    {
        tblShow.Width = (int)_boardSize;
        tblPicker.Width = (int)_boardSize;
        int increment = ((int)_boardSize / (int)_fineness);

        cellPal1.Attributes.Add("onClick", Page.ClientScript.GetPostBackEventReference(this, "pal1"));
        cellPal2.Attributes.Add("onClick", Page.ClientScript.GetPostBackEventReference(this, "pal2"));
        cellPal3.Attributes.Add("onClick", Page.ClientScript.GetPostBackEventReference(this, "pal3"));
        cellPal4.Attributes.Add("onClick", Page.ClientScript.GetPostBackEventReference(this, "pal4"));
        cellPal5.Attributes.Add("onClick", Page.ClientScript.GetPostBackEventReference(this, "pal5"));

        string tmpCol;

        for (int x = 0; x <= (int)_boardSize; x += increment)
        {
            TableRow tr = new TableRow();
            for (int y = 0; y <= (int)_boardSize; y += increment)
            {
                tmpCol = getColor(x, y);
                TableCell tc = new TableCell();
                tc.Attributes.Add("bgcolor", tmpCol);
                tc.Attributes.Add("width", increment.ToString());
                tc.Attributes.Add("height", increment.ToString());
                tc.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(this, tmpCol));
                tr.Cells.Add(tc);

            }
            tblPicker.Rows.Add(tr);

            //Render the completed tables
            tblShow.RenderControl(writer);
            tblPicker.RenderControl(writer);
            
        }
    }

    public enum Size
    {
        Large = 256,
        Medium = 128,
        Small = 64
    }

    public enum Resolution
    {
        Fine = 32,
        Medium = 16,
        Coarse = 4
    }

    private Resolution _fineness = Resolution.Medium;

    public Resolution Fineness
    {
        get { return _fineness; }
        set { _fineness = value; }
    }

    private Size _boardSize = Size.Medium;

    public Size BoardSize
    {
        get { return _boardSize; }
        set { _boardSize = value; }
    }

    private string Palette
    {
        get { return (string)ViewState["Palette"]; }
        set { ViewState["Palette"] = value; }
    }

    public Color SelectedColor
    {
        get
        {
            try
            {
                return (Color)ViewState["selectedColor"];
            }
            catch (NullReferenceException)
            {
                return Color.White;
            }
        }
        set { ViewState["selectedColor"] = value; }
    }

    private string getColor(int x, int y)
    {
        int xmod = (int)((255F / (float)_boardSize) * (float)x);
        int ymod = (int)((255F / (float)_boardSize) * (float)y);

        int r = 0, g = 0, b = 0;

        switch (Palette)
        {
            case "pal1":
                r = xmod;
                g = ymod;
                break;
            case "pal2":
                g = xmod;
                b = ymod;
                break;
            case "pal3":
                r = xmod;
                b = ymod;
                break;
            case "pal4":
                r = ymod;
                g = xmod;
                b = ymod;
                break;
            case "pal5":
                r = ymod;
                g = ymod;
                b = ymod;
                break;
            default:
                r = xmod;
                g = ymod;
                break;
        }

        return ColorTranslator.ToHtml(Color.FromArgb(r, g, b));
    }

    public void RaisePostBackEvent(string eventArgument)
    {
        switch (eventArgument)
        {
            case "pal1":
            case "pal2":
            case "pal3":
            case "pal4":
            case "pal5":
                Palette = eventArgument;
                break;
            default:
                try
                {
                    cellPreview.BackColor = ColorTranslator.FromHtml(eventArgument);
                    cellPreview.ForeColor = Color.FromArgb(~cellPreview.BackColor.ToArgb());
                    this.SelectedColor = cellPreview.BackColor;
                    cellPreview.Text = eventArgument;
                }
                catch (Exception)
                {

                }
                break;
        }

    }
}
}
